home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-2 / Inter.Net 55-2.iso / Mandrake / mdkinst / usr / bin / perl-install / resize_fat / main.pm < prev   
Encoding:
Perl POD Document  |  2000-01-12  |  4.5 KB  |  171 lines

  1. #!/usr/bin/perl
  2.  
  3. # DiskDrake
  4. # Copyright (C) 1999 MandrakeSoft (pixel@linux-mandrake.com)
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2, or (at your option)
  9. # any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19.  
  20. # This is mainly a perl rewrite of the work of Andrew Clausen (libresize)
  21.  
  22. package resize_fat::main;
  23.  
  24.  
  25.  
  26.  
  27. use log;
  28. use common qw(:common :system :constant);
  29. use resize_fat::boot_sector;
  30. use resize_fat::info_sector;
  31. use resize_fat::directory;
  32. use resize_fat::io;
  33. use resize_fat::fat;
  34. use resize_fat::any;
  35.  
  36.  
  37. 1;
  38.  
  39.  
  40. sub new($$$) {
  41.     my ($type, $device, $fs_name) = @_;
  42.     my $fs = { device => $device, fs_name => $fs_name } ;
  43.  
  44.     resize_fat::io::open($fs);
  45.     resize_fat::boot_sector::read($fs);
  46.     $resize_fat::isFAT32 and eval { resize_fat::info_sector::read($fs) };
  47.     resize_fat::fat::read($fs);
  48.     resize_fat::any::flag_clusters($fs);
  49.  
  50.     bless $fs, $type;
  51. }
  52.  
  53. sub DESTROY { resize_fat::c_rewritten::free_all() }
  54.  
  55.  
  56.  
  57.  
  58. sub copy_clusters {
  59.     my ($fs, $cluster) = @_;
  60.     my @buffer;
  61.     my $flush = sub {
  62.     while (@buffer) {
  63.         my $cluster = shift @buffer;
  64.         resize_fat::io::write_cluster($fs, $cluster, shift @buffer);
  65.     }
  66.     };
  67.     for (; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
  68.     resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::FILE or next;
  69.     push @buffer, 
  70.       resize_fat::c_rewritten::fat_remap($cluster), 
  71.       resize_fat::io::read_cluster($fs, $cluster);
  72.     @buffer > 50 and &$flush();
  73.     }
  74.     &$flush();
  75. }
  76.  
  77.  
  78. sub construct_dir_tree {
  79.     my ($fs) = @_;
  80.  
  81.     if ($resize_fat::isFAT32) {
  82.     
  83.     
  84.     resize_fat::c_rewritten::set_flag($fs->{fat32_root_dir_cluster}, $resize_fat::any::FREE);
  85.     }
  86.  
  87.     for (my $cluster = 2; $cluster < $fs->{nb_clusters} + 2; $cluster++) {
  88.     resize_fat::c_rewritten::flag($cluster) == $resize_fat::any::DIRECTORY or next;
  89.  
  90.       resize_fat::io::write_cluster($fs,
  91.                     resize_fat::c_rewritten::fat_remap($cluster),
  92.                     resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster)));
  93.     }
  94.  
  95.     sync();
  96.  
  97.     
  98.     
  99.     #
  100.     
  101.  
  102.     
  103.     if ($resize_fat::isFAT32) {
  104.     my $cluster = $fs->{fat32_root_dir_cluster};
  105.  
  106.     resize_fat::io::write_cluster($fs,
  107.               resize_fat::c_rewritten::fat_remap($cluster),
  108.               resize_fat::directory::remap($fs, resize_fat::io::read_cluster($fs, $cluster)));
  109.     } else {
  110.     resize_fat::io::write($fs, $fs->{root_dir_offset}, $fs->{root_dir_size},
  111.                   resize_fat::directory::remap($fs, resize_fat::io::read($fs, $fs->{root_dir_offset}, $fs->{root_dir_size})));
  112.     }
  113. }
  114.  
  115. sub min_size($) { &resize_fat::any::min_size }
  116. sub max_size($) { &resize_fat::any::max_size }
  117.  
  118.  
  119.  
  120.  
  121.  
  122. sub resize {
  123.     my ($fs, $size) = @_;
  124.  
  125.     my ($min, $max) = (min_size($fs), max_size($fs));
  126.  
  127.  
  128.     $size += $min if $size =~ /^\+/;
  129.  
  130.     $size >= $min or die "Minimum filesystem size is $min sectors";
  131.     $size <= $max or die "Maximum filesystem size is $max sectors";
  132.  
  133.     log::l("resize_fat: Partition size will be ", $size * $SECTORSIZE >> 20, "Mb (well exactly ${size} sectors)");
  134.  
  135.     my $new_data_size = $size * $SECTORSIZE - $fs->{cluster_offset};
  136.     my $new_nb_clusters = divide($new_data_size, $fs->{cluster_size});
  137.  
  138.     log::l("resize_fat: Allocating new clusters");
  139.     resize_fat::fat::allocate_remap($fs, $new_nb_clusters);
  140.  
  141.     log::l("resize_fat: Copying files");
  142.     copy_clusters($fs, $new_nb_clusters);
  143.  
  144.     log::l("resize_fat: Copying directories");
  145.     construct_dir_tree($fs);
  146.  
  147.     log::l("Writing new FAT...");
  148.     resize_fat::fat::update($fs);
  149.     resize_fat::fat::write($fs);
  150.  
  151.     $fs->{nb_sectors} = $size;
  152.     $fs->{nb_clusters} = $new_nb_clusters;
  153.     $fs->{clusters}{count}->{free} =
  154.     $fs->{nb_clusters} - $fs->{clusters}{count}->{used} - $fs->{clusters}->{count}->{bad} - 2;
  155.  
  156.     $fs->{system_id} = 'was here!';
  157.     $fs->{small_nb_sectors} = 0;
  158.     $fs->{big_nb_sectors} = $size;
  159.  
  160.     log::l("resize_fat: Writing new boot sector...");
  161.  
  162.     resize_fat::boot_sector::write($fs);
  163.  
  164.     $resize_fat::isFAT32 and eval { resize_fat::info_sector::write($fs) }; 
  165.  
  166.     sync();
  167.     close $fs->{fd};
  168.     log::l("resize_fat: done");
  169. }
  170.  
  171.